package cn.tedu.knows.faq.service.impl;


import cn.tedu.knows.commons.model.Tag;
import cn.tedu.knows.faq.mapper.TagMapper;
import cn.tedu.knows.faq.service.ITagService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author tedu.cn
 * @since 2021-05-25
 */
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements ITagService {

    //因为当前业务逻辑层是单例Spring保存
    //所以这个类中声明的成员变量也只在内存中出现一份
    //我们可以通过声明List类型的成员变量充当缓存

    private List<Tag> tags=new CopyOnWriteArrayList<>();

    //缓存所有标签的Map
    private Map<String,Tag> name2TagMap=
                    new ConcurrentHashMap<>();

    @Override
    public List<Tag> getTags() {
        //当需要获得所有标签时,先检查缓存中是否已经有标签
        if(tags.isEmpty()){
            synchronized (tags) {
                if(tags.isEmpty()) {
                    //启动list()是数据库查询所有标签
                    //tags.addAll是将这些标签保存到tags对象中
                    tags.addAll(list());
                    //新增信息到tags后立即将,map也赋值
                    for(Tag t: tags){
                        name2TagMap.put(t.getName(),t);
                    }
                }
            }
        }
        // 1 2  3
        return tags;
    }

    @Override
    public Map<String, Tag> name2TagMap() {
        //如果map没有值
        if(name2TagMap.isEmpty()){
            //去调用getTags方法
            //getTags中有严格的线程锁,这里就不需要限制了
            getTags();
        }
        return name2TagMap;
    }
}
